import java.io.*;
import java.util.*;
import java.lang.*;
import java.math.*;
import java.util.concurrent.*;

public class Exp implements Runnable {
    static Integer o1 = new Integer(1);
    static Integer o2 = new Integer(2);
    static Thread t1;
    static Thread t2;

    public static void main(String[] args) {
        t1 = new Thread(new Exp());
        t2 = new Thread(new Exp());

        t1.start();
        t2.start();
    }

    public void run() {
        if (Thread.currentThread() == t1) o1First();
        else o2First();
    }

    private static void o1First() {
        System.out.println("t1: Awaiting lock on o1...");
        synchronized (o1) {
            System.out.println("\tt1: Acquired");
            try {
                Thread.sleep(100);
            }
            catch (InterruptedException ex) {

            }
            System.out.println("t1: Awaiting lock on o2...");
            synchronized (o2) {
                System.out.println("\tt1: Acquired");
            }
        }
    }

    private static void o2First() {
        System.out.println("t2: Awaiting lock on o2...");
        synchronized (o2) {
            System.out.println("\tt2: Acquired");
            try {
                Thread.sleep(100);
            }
            catch (InterruptedException ex) {

            }
            System.out.println("t2: Awaiting lock on o1...");
            synchronized (o1) {
                System.out.println("\tt2: Acquired");
            }
        }
    }
}